Release 10.1A: OpenEdge Development:
Programming Interfaces


Managing database connection IDs

By default, OpenEdge authorizes all permissions for database and auditing operations using the database connection ID established for each connected OpenEdge RDBMS. You can set the database connection ID for a database from two basic sources:

  1. A user ID authenticated using the OpenEdge internal authentication system (_User table).
  2. A user ID authenticated using an external authentication system.

If you do not set a database connection ID for a database, the database connection ID is considered blank. You can also clear an existing database connection ID, which resets the effective ID to blank.

Setting a database connection ID from the OpenEdge internal authentication system

Any user ID that you authenticate using the _User table becomes the database connection ID by default, whether you authenticate it using the User ID (-U) and Password (-P) connection parameters in the4GL CONNECT statement or using the SETUSERID function. If you do nothing else, the database where you set this connection ID authorizes all of its operations using this database connection ID.

However, you can also add a client login session to your application for this database connection ID by creating and initializing a client-principal object for it (see the "Managing client login sessions" section). If you only require that this database connection ID be used in the Progress session where it is authenticated, you do not need to further assert and validate the identity associated with this client-principal object beyond logging in and sealing the client principal object using the SEAL( ) method with any access code value that you choose. If your database options are set to record client login sessions, this is sufficient to record the client login session in the database, and also to provide login session context for auditing (if enabled).

Thus, you might use a code fragment such as this, which sets up an internally authenticated client login session and sets the database connection ID for an inventory database (already connected). The bold-faced code features the client login session management and authentication elements:

Login session for an internally authenticated database connection ID
DEFINE VARIABLE hCP AS HANDLE NO-UNDO. 
DEFINE VARIABLE cUserID AS CHARACTER NO-UNDO. 
DEFINE VARIABLE cPassword AS CHARACTER NO-UNDO. 
/* Get user ID and password */ 
... 
cUserID = ... 
cPassword = ... 
/* Create and initialize client-principal for use 
   with Inventory database */ 
CREATE CLIENT-PRINCIPLE hCp. 
hCP:SESSION-ID = "Inventory:" + cUserID + STRING(NOW). 
hCP:USER-ID = cUserID. 
hCP:DOMAIN-NAME = "InventoryDB". 
/* Authenticate and login database connection ID 
   session for the single database connection */ 
If SETUSERID(cUserID, cPassword) THEN 
    hCP:SEAL("AlwaysValid"). 
ELSE 
    hCP:AUTHENTICATION-FAILED("User not authenticated."). 
/* Handle results of authentication */ 
IF hCP:LOGIN-STATE = "LOGIN" THEN DO: /* Do Inventory stuff... */ 
    ... 
    hCP:LOGOUT(). 
    DELETE OBJECT hCP. 
END. 
ELSE DO: /* Exit with message from AUTHENTICATION-FAILED() method */ 
    RETURN hCP:LOGIN-STATE + ": " + hCP:STATE-DETAIL. 
    DELETE OBJECT hCP. 
END. 

In this code fragment, the setting of the SESSION-ID attribute, which includes the value of STRING(NOW), while valid is not necessarily unique. If you enable auditing for the application, where unique references are more important, use the GENERATE-UUID function to set the SESSION-ID attribute. For more information, see the "Creating and managing unique object identities" section.

Also, in this fragment, the access code value ("AlwaysValid") that you use to seal the client-principal object can be anything. Since you are not validating your database connection ID in the client login session against a trusted domain registry and the login session does not survive the Progress session, the security risk is minimal. In this case, you are likely creating the login session only to record its context.

If you do have reason to validate the database connection ID using the client-principal object, you must register a domain entry for the _User table in the OpenEdge RDBMS’s trusted domain registry and manage the client-principal object as if it represents an externally authenticated user identity (see the "Setting a database connection ID from an external authentication system" section). A common reason to do this is to transport and use the same login session information between multiple Progress sessions within your application environment (see the "Managing application user IDs in n-tier applications" section).

Setting a database connection ID from an external authentication system

If you choose to set the database connection ID from a user ID that you authenticate externally, you must have a corresponding domain entry registered in a trusted domain registry. By default, this registry must be the OpenEdge RDBMS’s trusted domain registry.

Note: You can set multiple database connection IDs using a single client-principal object by configuring database options to have each database trust the application domain registry. In this case, the database connection ID essentially is and is managed exactly as a Progress session ID (see the "Managing Progress session IDs" section). For more information on setting database options to trust the application domain registry, see the sections on synchronizing user identities in OpenEdge Getting Started: Core Business Services and the online help on setting database options in Data Administration.

Any user ID that you authenticate with an external authentication system has no OpenEdge-supported functional identity until you specifically assert and validate that identity against the corresponding authentication domain. This you must do using a client-principal object.

To assert and validate an externally authenticated database connection ID:

  1. Input the candidate user ID and authentication criteria (password, for example).
  2. Create and initialize a client-principal object with the user ID and corresponding authentication domain information that is in your database trusted domain registry.
  3. Authenticate the user ID through the external authentication system.
  4. If the authentication succeeds, proceed to Step 5. If the authentication fails, invalidate the client-principal object with the AUTHENTICATION-FAILED( ) method and proceed or exit the procedure accordingly.
  5. Log in the client session and seal the client-principal object using the access code assigned to your authentication domain.
  6. Assert and validate the authenticated user ID represented by the client-principal object as the database connection ID for your database (or databases) using the 4GL SET-DB-CLIENT function. The SET-DB-CLIENT function validates the client-principal object against a database trusted domain registry in order to set the corresponding database connection ID. Optionally, this can be the application domain registry, instead of the database’s own domain registry. For more information, see the "Managing Progress session IDs" section.
  7. Manage the rest of the client login session as usual (see the "Managing client login sessions" section).

Thus, you might use a code fragment such as this, which sets up an externally authenticated client login session in order to set a database connection ID for an inventory database (already connected). The bold-faced code features the client login session management and authentication elements:

Login session for an externally authenticated database connection ID
DEFINE VARIABLE hCP AS HANDLE NO-UNDO. 
DEFINE VARIABLE hAuthProc AS HANDLE NO-UNDO. 
DEFINE VARIABLE cUserID AS CHARACTER NO-UNDO. 
DEFINE VARIABLE cPassword AS CHARACTER NO-UNDO. 
DEFINE VARIABLE cAccessCode AS CHARACTER NO-UNDO. 
/* Declare external authentication functions */ 
FUNCTION authenticateMyUser RETURNS LOGICAL  
    (INPUT cUserID AS CHARACTER, INPUT cPassword AS CHARACTER) IN hAuthProc. 
FUNCTION getAccessCode RETURNS CHARACTER IN hAuthProc. 
/* Get user ID/password and instantiate external authentication object, 
   which also provides the authentication domain access code */ 
... 
cUserID = ... 
cPassword = ... 
RUN MyAuthentication.p PERSISTENT SET hAuthProc. 
cAccessCode = getAccessCode(). 
/* Create and initialize a client-principal for use with an  
   authentication domain in the database domain registry */ 
CREATE CLIENT-PRINCIPLE hCp. 
hCP:SESSION-ID = "Inventory:" + cUserID + STRING(NOW). 
hCP:USER-ID = cUserID. 
hCP:DOMAIN-NAME = "DatabaseUsers". 
/* Authenticate and login database connection ID 
   session for the single database connection */ 
If authenticateMyUser(cUserID, cPassword) THEN DO: 
    hCP:SEAL(cAccessCode). 
    IF NOT SET-DB-CLIENT(hCP) THEN DO: 
        hCP:LOGOUT(). 
        cRetVal = "User ID not valid DB connection ID". 
    END. 
END. 
ELSE DO: 
    hCP:AUTHENTICATION-FAILED("User not authenticated."). 
    cRetVal = hCP:LOGIN-STATE + ": " + hCP:STATE-DETAIL. 
END. 
/* Handle results of authentication */ 
IF hCP:LOGIN-STATE = "LOGIN" THEN DO: /* Do Inventory stuff... */ 
    ... 
    /* Clear the database connection ID to end the login session */ 
    hCP:LOGOUT(). 
    DELETE OBJECT hCP. 
END. 
ELSE DO: /* Exit with failure message */ 
    RETURN cRetVal. 
    DELETE OBJECT hCP. 
END. 

In this fragment, the domain access code used by the application is maintained and returned by the same authentication procedure (MyAuthentication.p) that authenticates the user ID. This value, returned using the getAccessCode user-defined function, must match the access code configured for the authentication domain entry in the OpenEdge RDBMS’s trusted domain registry.

Also in this code fragment, the setting of the SESSION-ID attribute, which includes the value of STRING(NOW), while valid is not necessarily unique. If you enable auditing for the application, where unique references are more important, use the GENERATE-UUID function to set the SESSION-ID attribute. For more information, see the "Creating and managing unique object identities" section.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095